﻿using System;
using System.Text;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Layout;

namespace YTLog
{
    public class LoggerMaker
    {
        static LoggerMaker()
        {
            foreach (var name in Enum.GetNames(typeof(LogType)))
            {
                var repo = LogManager.CreateRepository(name);

                var layout = new PatternLayout()
                {
                    ConversionPattern = "%newline[%date][%thread][%logger][%level]【%message】",
                };

                var rfAppender = new RollingFileAppender()
                {
                    Name = name,
                    File = $"Log/Text/{name}.log",
                    PreserveLogFileNameExtension = true,
                    StaticLogFileName = false,

                    RollingStyle = RollingFileAppender.RollingMode.Size,
                    MaxFileSize = 10 * 1024 * 1024,     //默认值10MB (10*1024*1024);
                    MaxSizeRollBackups = 10,

                    AppendToFile = true,                //是否在文件中追加,设为false则将以前的记录覆盖;
                    ImmediateFlush = true,              //是否即时写入文件;
                    Layout = layout,

                    Encoding = Encoding.UTF8,
                };

                layout.ActivateOptions();
                rfAppender.ActivateOptions();
                BasicConfigurator.Configure(repo, rfAppender);
            }
        }

        public static void WriteLog(LogType type, LogLevel level, object message)
        {
            var logger = LogManager.GetLogger(type.ToString(), type.ToString());
            switch (level)
            {
                case LogLevel.Debug:
                    logger.Debug(GetMessageString(message));
                    break;

                case LogLevel.Info:
                    logger.Info(GetMessageString(message));
                    break;

                case LogLevel.Warn:
                    logger.Warn(GetMessageString(message));
                    break;

                case LogLevel.Error:
                    logger.Error(GetMessageString(message));
                    break;

                case LogLevel.Fatal:
                    logger.Fatal(GetMessageString(message));
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(level), level, null);
            }
        }

        private static string GetMessageString(object message)
        {
            if (message is string)
                return message.ToString();
            try
            {
                return message.ToJsonString();
            }
            catch (Exception)
            {
                return message.ToString();
            }
        }
    }
}